package com.ruoyi.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.domain.AOrders;
import com.ruoyi.system.domain.AProduct;
import com.ruoyi.system.domain.ASetmeal;
import com.ruoyi.system.domain.OrderDetails;
import com.ruoyi.system.domain.vo.MyOrdersVo;
import com.ruoyi.system.mapper.AOrdersMapper;
import com.ruoyi.system.mapper.OrderDetailsMapper;
import com.ruoyi.system.service.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.swing.text.html.Option;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.domain.AjaxResult.error;
import static com.ruoyi.common.core.domain.AjaxResult.success;
import static com.ruoyi.common.utils.ShiroUtils.getSysUser;

@Controller
@RequestMapping("/user")
public class UserController {
    @Resource
    private ISysUserService userService;

    @Autowired
    private SysPasswordService passwordService;

    @Resource
    private OrderDetailsMapper orderDetailsMapper;

    @Resource
    private AOrdersMapper ordersMapper;

    @Resource
    private IAProductService productService;

    @Resource
    private IASetmealService setmealService;

    @GetMapping("/loginPage")
    public String loginPage() {
        return "user/login";
    }


    @GetMapping("/index")
    public String index() {
        return "user/index";
    }

    @PostMapping("/login")
    @ResponseBody
    public AjaxResult userLogin(String username, String password, Boolean rememberMe)
    {
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        Subject subject = SecurityUtils.getSubject();
        try
        {
            subject.login(token);
            return success();
        }
        catch (AuthenticationException e)
        {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    /**
     * 获取用户信息
     * @return
     */
    @PostMapping("/getUserInfo")
    @ResponseBody
    public AjaxResult getUserInfo(){
        SysUser sysUser = getSysUser();
        return AjaxResult.success(sysUser);
    }

    /**
     * 修改密码
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @PostMapping("/resetPwd")
    @ResponseBody
    public AjaxResult resetPwd(String oldPassword, String newPassword)
    {
        SysUser user = getSysUser();
        if (!passwordService.matches(user, oldPassword))
        {
            return error("修改密码失败，旧密码错误");
        }
        if (passwordService.matches(user, newPassword))
        {
            return error("新密码不能与旧密码相同");
        }
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
        user.setPwdUpdateDate(DateUtils.getNowDate());
        if (userService.resetUserPwd(user) > 0)
        {
            ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
            return success();
        }
        return error("修改密码异常，请联系管理员");
    }

    /**
     * 获取我的订单信息
     * @return
     */
    @PostMapping("/getMyOrderList")
    @ResponseBody
    public AjaxResult getMyOrderList(){
        SysUser sysUser = getSysUser();
        Long userId = sysUser.getUserId();
//        查询订单主表
        LambdaQueryWrapper<AOrders> ordersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ordersLambdaQueryWrapper.select(AOrders::getId,AOrders::getOrderCustomer);
        ordersLambdaQueryWrapper.eq(AOrders::getOrderCustomer,userId);
        List<AOrders> aOrders = ordersMapper.selectList(ordersLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(aOrders)){
            return AjaxResult.success(new ArrayList<>());
        }
//        获取订单主表id集合
        List<Long> orderIds = aOrders.stream().map(AOrders::getId).collect(Collectors.toList());
//        查询子表
        LambdaQueryWrapper<OrderDetails> orderDetailsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailsLambdaQueryWrapper.select(OrderDetails::getId,
                OrderDetails::getProductId,
                OrderDetails::getSetmealId,
                OrderDetails::getQuantity,
                OrderDetails::getCreateTime
        );
        orderDetailsLambdaQueryWrapper.in(OrderDetails::getOrderId,orderIds);
        List<OrderDetails> orderDetails = orderDetailsMapper.selectList(orderDetailsLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(orderDetails)){
            return AjaxResult.success(new ArrayList<>());
        }
//      构建返回集合
        List<MyOrdersVo> myOrdersVos = new ArrayList<>();
        orderDetails.forEach(item -> {
            Long productId = item.getProductId();
            Long setmealId = item.getSetmealId();

            if (ObjectUtils.isNotEmpty(productId)){
                AProduct aProduct = productService.selectAProductById(productId);
                if (ObjectUtils.isEmpty(aProduct)){
                    return;
                }
                MyOrdersVo build = MyOrdersVo.builder()
                        .title(aProduct.getProductName())
                        .amount(aProduct.getProductPrice())
                        .quantity(item.getQuantity())
                        .createTime(item.getCreateTime())
                        .imgUrl(aProduct.getImgUrl())
                        .build();
                myOrdersVos.add(build);
            }

            if (ObjectUtils.isNotEmpty(setmealId)){
                ASetmeal aSetmeal = setmealService.selectASetmealById(setmealId);
                if (ObjectUtils.isEmpty(aSetmeal)){
                    return;
                }
                MyOrdersVo build = MyOrdersVo.builder()
                        .title(Optional.ofNullable(aSetmeal).map(ASetmeal::getSetmealName).orElse(""))
                        .quantity(item.getQuantity())
                        .amount(Double.valueOf(aSetmeal.getSetmealPrice()))
                        .createTime(item.getCreateTime())
                        .imgUrl(aSetmeal.getImgUrl())
                        .build();
                myOrdersVos.add(build);
            }
        });

        return AjaxResult.success(myOrdersVos);
    }


}
